'''
A Go board vertex.
'''

import string

class Vertex:
    """ 
    A board position vertex. The coordinates are zero-based, stored
    in vertex.x and vertex.y, y = 0 being the bottom of the board.
    """
    
    VALID_BOARD_LETTERS = string.ascii_lowercase.replace('i', '')
    VALID_BOARD_NUMBERS = [str(i) for i in range(1, 26)]
    
    @classmethod
    def PASS(cls):
        """ Returns the pass vertex """
        
        vertex = Vertex(-1, -1)
        vertex._is_pass = True
        
        return vertex        
    
    @classmethod
    def from_string(cls, vertex_string):
        
        if len(vertex_string) < 2:
            raise InvalidBoardVertexError()
        
        vertex_string = vertex_string.strip().lower()
        
        if vertex_string == 'pass':
            return Vertex.PASS()
        
        letter = vertex_string[0]
        number = vertex_string[1:]        
        
        if letter not in cls.VALID_BOARD_LETTERS:
            raise InvalidBoardVertexError()
        
        if not number.isdigit() or int(number) > 25:
            raise InvalidBoardVertexError()        
        
        x = cls.VALID_BOARD_LETTERS.find(letter)
        y = int(number) - 1
        
        return Vertex(x, y)
        
    
    def __init__(self, x, y):
        
        if x > 25 or y > 25:
            raise InvalidBoardVertexError()
        
        self.x = x
        self.y = y
        
        self._is_pass = False
         
     
    def __str__(self):
        
        if self._is_pass:
            return 'pass'
        
        return '%s%d' % (self.VALID_BOARD_LETTERS[self.x], self.y + 1)
    
    def __eq__(self, other):
        return ((self.x == other.x and self.y == other.y) 
                            and (self._is_pass == other._is_pass)) 
    
    def __hash__(self):
        return hash((self.x, self.y))
    

class InvalidBoardVertexError(Exception):
        pass
